const pickHeadObj = {
  year: { heads: ["年"], columns: ["years"] },
  month: { heads: ["月"], columns: ["months"] },
  date: { heads: ["年", "月", "日"], columns: ["years", "months", "days"] },
  time: { heads: ["时", "分", "秒"], columns: ["hours", "minites", "seconds"] },
  "date-time": {
    heads: ["年", "月", "日", "时", "分", "秒"],
    columns: ["years", "months", "days", "hours", "minites", "seconds"],
  },
  "date-hour": {
    heads: ["年", "月", "日", "时"],
    columns: ["years", "months", "days", "hours"],
  },
  "year-month": {
    heads: ["年", "月"],
    columns: ["years", "months"],
  },
  "month-day": {
    heads: ["月", "日"],
    columns: ["months", "days"],
  },
  "hour-minite": {
    heads: ["时", "分"],
    columns: ["hours", "minites"],
  },
  "month-day-hour-minite": {
    heads: ["月", "日", "时", "分"],
    columns: ["months", "days", "hours", "minites"],
  },
  "month-day-hour": {
    heads: ["月", "日", "时"],
    columns: ["months", "days", "hours"],
  },
};
const checkTimeShow = (index) => {
  if (index < 10) {
    return `0${index}`;
  }
  return index;
};
const getDaysLength = (year, month) => {
  const days = new Date(year, month, 0);
  return days.getDate();
};
const getFormatTimeValue = (type = "date-time", pickerColunm, dateList) => {
  const { years, months, days, hours, minites, seconds } = pickerColunm;
  if (type === "date-time") {
    return `${years[dateList[0]]}-${months[dateList[1]]}-${days[dateList[2]]} ${
      hours[dateList[3]]
    }:${minites[dateList[4]]}:${seconds[dateList[5]]}`;
  }
  if (type === "year") {
    return years[dateList[0]];
  }
  if (type === "month") {
    return months[dateList[0]];
  }
  if (type === "date") {
    return `${years[dateList[0]]}-${months[dateList[1]]}-${days[dateList[2]]}`;
  }
  if (type === "time") {
    return `${hours[dateList[0]]}:${minites[dateList[1]]}:${
      seconds[dateList[2]]
    }`;
  }
};
const getInitDateList = (pickerColumnList = {}, config = {}) => {
  const { month = 1, day = 1, hour = 0, minite = 0, second = 0 } = config;
  const { years, months, days, hours, minites, seconds } = pickerColumnList;
  let obj = {
    years: years[10],
    months: months[month - 1],
    days: days[day - 1],
    hours: hours[hour],
    minites: minites[minite],
    seconds: seconds[second],
  };
  return obj;
};
// 这里是组件开始的地方
// picker小组件
function Picker(props) {
  const { useState, useEffect } = React;
  const {
    lineHeight = 50,
    list = [],
    changeVal = () => {},
    type,
    initData = "",
  } = props;
  const [startY, setStartY] = useState(0);
  const [moveY, setMoveY] = useState(0);
  const [targetY, setTargetY] = useState(0);
  const [positionStyle, setPosition] = useState({});
  const [theList, setList] = useState(list);
  const [currentDay, setCurrentDay] = useState("no");

  useEffect(() => {
    let positionIndex = list.filter(
      (item) => Number(item) === Number(initData)
    );
    // 这里是完全可以优化的
    if (type === "years" && !positionIndex.length) {
      let mylist = Array.from({ length: 20 }, (_, index) => {
        return Number(initData) - 10 + index;
      });
      setList([...mylist]);
      positionIndex = mylist.filter(
        (item) => Number(item) === Number(initData)
      );
      positionIndex = mylist.indexOf(positionIndex[0]);
    } else if (type === "days") {
      setList([...list]);
      if (currentDay === "no") {
        setCurrentDay(initData - 1);
        return;
      }
      if (Number(currentDay) <= list.length - 1) {
        positionIndex = currentDay;
      } else {
        positionIndex = list.length - 1;
      }
      changeVal({ days: positionIndex + 1 });
      setTargetY(positionIndex);
      setCurrentDay(positionIndex);
    } else {
      positionIndex = list.indexOf(positionIndex[0]);
    }
    let initPosition = {
      transform: `translate3d(0, -${lineHeight * positionIndex}px, 0)`,
    };
    setTargetY(Number(`-${lineHeight * positionIndex}`));
    setPosition(initPosition);
  }, [initData, type, list, currentDay]);

  const getStartY = (e) => {
    e = e || window.event;
    setStartY(e.changedTouches[0].clientY);
  };
  const addMoveAnimation = (e) => {
    e = e || window.event;
    let moveY = e.changedTouches[0].clientY - startY;
    let target = moveY + targetY;
    let start = e.changedTouches[0].clientY;
    setMoveY(moveY);
    setTargetY(target);
    setStartY(start);
    let style = { transform: `translate3d(0, ${target}px, 0)` };
    setPosition(style);
  };
  // 结束的时候还要设定值
  const addPositionAnimation = (e) => {
    e = e || window.event;
    setPosition({ ...positionStyle, transition: "transform 0.3s ease" });
    const myRound = (x, y) => {
      x = -x;
      const ret = x / y - parseInt(x / y);
      if (ret > 0.3) {
        return -(parseInt(x / y) + 1);
      } else {
        return -parseInt(x / y);
      }
    };
    let target = 0;
    if (targetY >= 0) {
      target = 0;
    } else if (targetY <= -(list.length - 1) * lineHeight) {
      target = -(list.length - 1) * lineHeight;
    } else {
      target = myRound(targetY, lineHeight) * lineHeight;
    }
    setTargetY(target);
    let style = {
      transform: `translate3d(0, ${target}px, 0)`,
      transition: "transform 0.3s ease",
    };
    setPosition(style);
    let obj = {};
    obj[type] = theList[Math.abs(target) / lineHeight];
    if (type === "days") {
      setCurrentDay(theList[Math.abs(target) / lineHeight]);
    }
    changeVal(obj);
  };
  const finishAnimation = () => {
    let obj = { ...positionStyle };
    delete obj.transition;
    setPosition({ ...obj });
  };
  return (
    <div className="the-picker-column">
      <div
        className="the-picker-mask"
        onTouchStart={getStartY}
        onTouchMove={addMoveAnimation}
        onTouchEnd={addPositionAnimation}
      ></div>
      <div
        className="the-picker-box"
        style={positionStyle}
        onTransitionEnd={finishAnimation}
      >
        {theList.map((item) => {
          return <div>{item}</div>;
        })}
      </div>
    </div>
  );
}
// datePicker组件
function DatePicker(props, ref) {
  const { useMemo, useState, useEffect, useImperativeHandle } = React;
  const [type, setType] = useState("date-time");
  const [showModal, setShowModal] = useState(false);
  const [columnList, setColumnList] = useState({});
  const [initDateList, setInitDataList] = useState({});
  const [timeData, setTimeData] = useState({});
  useImperativeHandle(ref, () => ({
    getTimeData,
    openDatePicker,
  }));
  useEffect(() => {
    const date = new Date();
    // 获取当前日期和时间
    let year = date.getFullYear();
    let month = date.getMonth() + 1;
    let day = date.getDate();
    let hour = date.getHours();
    let minite = date.getMinutes();
    let second = date.getSeconds();
    // 这里还要考虑万一里面有很老的值之后的显示兜底
    let years = Array.from({ length: 20 }, (_, index) => {
      return year - 10 + index;
    });
    let months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
    let daysLength = getDaysLength(year, month);
    if (JSON.stringify(timeData) !== "{}") {
      let y = !!timeData.years ? timeData.years : year;
      let m = !!timeData.months ? timeData.months : month;
      daysLength = getDaysLength(y, m);
    }
    let days = Array.from({ length: daysLength }, (_, index) => index + 1);
    let hours = Array.from({ length: 24 }, (_, index) => checkTimeShow(index));
    let minites = Array.from({ length: 60 }, (_, index) =>
      checkTimeShow(index)
    );
    const pickerColumnList = {
      years,
      months,
      days,
      hours,
      minites, // 秒和分共用这一套
      seconds: minites,
    };
    setColumnList({ ...pickerColumnList });
    // 这里准备优化时间部分
    let initDateList = getInitDateList(pickerColumnList, {
      month,
      day,
      hour,
      minite,
      second,
    });
    setInitDataList({ ...initDateList });
    // =======================
  }, [type, timeData]);
  const closeModal = () => {
    // 可能需要修改
    setShowModal(false);
  };
  const getTimeData = () => {
    if (JSON.stringify(timeData) === "{}") {
      return null;
    }
    return { ...timeData };
  };
  const openDatePicker = async (params) => {
    const { type = "date-time", value = {} } = params;
    if (JSON.stringify(value) === "{}" || !value) {
      // 获取默认的值
    } else {
      // 填充塞进来的值,但是还是要考虑智能设置时间组件的滑动
      $React.DatePickerData = { ...value };
      setTimeData({ ...value });
    }
    await setType(type);
    await setInitDataList({ ...value });
    await setShowModal(true);
  };
  const stopModal = (e) => {
    e.stopPropagation();
    return false;
  };
  const setDateTimeData = () => {
    setTimeData({ ...initDateList, ...$React.DatePickerData });
    setInitDataList({ ...initDateList, ...$React.DatePickerData });
    closeModal();
  };
  const changeVal = (data) => {
    let obj = { ...$React.DatePickerData, ...data };
    $React.DatePickerData = obj;
    if (data.years || data.months) {
      let year = data.years || $React.DatePickerData.years;
      let month = data.months || $React.DatePickerData.months;
      const days = new Date(year, month, 0);
      let list = Array.from(
        { length: days.getDate() },
        (_, index) => index + 1
      );
      let newList = { ...columnList, days: [...list] };
      setColumnList({ ...newList });
    }
  };
  const pickerHead = useMemo(() => {
    const itemStyle = {
      width: `${100 / pickHeadObj[type].heads.length}%`,
      textAlign: "center",
    };
    return pickHeadObj[type].heads.map((item, index) => {
      return (
        <div key={index} style={itemStyle}>
          {item}
        </div>
      );
    });
  }, [type]);
  const pickerColumns = useMemo(() => {
    if (JSON.stringify(columnList) === "{}") {
      console.log("准备渲染DatePicker");
      return null;
    }
    return pickHeadObj[type].columns.map((item) => {
      return (
        <Picker
          key={item}
          list={columnList[item]}
          initData={initDateList[item]}
          type={item}
          changeVal={changeVal}
        />
      );
    });
  }, [type, columnList, initDateList]);
  if (!showModal) {
    return null;
  }
  return (
    <div className="react-date-picker" onClick={closeModal}>
      <div className="the-modal" onClick={stopModal}>
        <div className="the-operation-box">
          <div onClick={closeModal}>取消</div>
          <div onClick={setDateTimeData}>完成</div>
        </div>
        <div className="date-picker-head">{pickerHead}</div>
        <div className="the-picker-head-line"></div>
        {/* 这里开始就很考验了 */}
        <div className="the-picker-view">{pickerColumns}</div>
      </div>
    </div>
  );
}

$React.DatePicker = ReactDOM.createRoot(document.getElementById("datePicker"));
$React.DatePicker.render(<DatePicker />);
